package com.gpj.learn.concurrent.jol.demo;

import com.gpj.learn.concurrent.jol.Example;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.CountDownLatch;

/**
 * @className JolDemo5
 * @description
 *   偏向锁、轻量锁与重量锁的变化
 * @author GPJ
 * @date 2020/6/15 8:38
 * @version 1.0
 **/
@Slf4j
public class JolDemo5 {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(5 * 1000);
        Example example = new Example();
        /**
         * 偏向锁，偏向状态(启用偏向所)
         * 00000101 00000000 00000000 00000000
         * 00000000 00000000 00000000 00000000
         * 无锁(关闭偏向所)
         * 00000001 00000000 00000000 00000000
         * 00000000 00000000 00000000 00000000
         */
        lockStatus("创建", example);

        Thread thread = new Thread(() -> {
            synchronized (example) {
                try {
                    /**
                     * 偏向锁，偏向线程threa(启用偏向所)
                     * 00000101 11001000 11110101 00011111
                     * 00000000 00000000 00000000 00000000
                     * 轻量锁(关闭偏向所)
                     * 11001000 11101111 10100111 00100000
                     * 00000000 00000000 00000000 00000000
                     */
                    lockStatus("单一线程启动", example);
                    Thread.sleep(5 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        Thread.sleep(3 * 1000);

        synchronized (example){
            /**
             * 重量锁(启用偏向所)
             * 01011010 11100011 01110101 00011100
             * 00000000 00000000 00000000 00000000
             * 重量锁(关闭偏向所)
             * 10001010 11010011 01111111 00011100
             * 00000000 00000000 00000000 00000000
             */
            lockStatus("双线程抢占锁", example);
        }
        /**
         * 重量锁(启用偏向所)
         * 00111010 00000000 01110111 00011100
         * 00000000 00000000 00000000 00000000
         * 重量锁(关闭偏向所)
         * 10001010 11010011 01111111 00011100
         * 00000000 00000000 00000000 00000000
         *
         */
        lockStatus("单一线程释放锁", example);

        thread.join();
        /**
         * 重量锁(启用偏向所)
         * 01011010 11100011 01110101 00011100
         * 00000000 00000000 00000000 00000000
         * 重量锁(关闭偏向所)
         * 10001010 11010011 01111111 00011100
         * 00000000 00000000 00000000 00000000
         */
        lockStatus("全部线程释放锁", example);

        System.gc();
        /**
         * 无锁(启用偏向所)
         * 00001001 00000000 00000000 00000000
         * 00000000 00000000 00000000 00000000
         * 无锁(关闭偏向所)
         * 00001001 00000000 00000000 00000000
         * 00000000 00000000 00000000 00000000
         */
        lockStatus("gc", example);
    }
    
    public static void lockStatus(String message, Example example){
        log.info("{}: {}", message, ClassLayout.parseInstance(example).toPrintable());
    }
}
